﻿module HtmlParserTests

open NUnit.Framework
open UriParsing
open HtmlScanner
open HtmlParser
open Dom
open HtmlDom
open DummyHost
open DocumentFactory



let parse html =
    let doc = createDocument (fun doc->()) blankUri (DummyLoader()) (DummyHost())
    parseHtmlTokens doc (scan html) 
    doc

[<Test>]
let testParseHtml() =
    //test code
    let html = """
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    test
    </body>
    </html>
    """
    let docNode = parse html
    let html = docNode.documentElement
    Assert.AreEqual(2, html.childElements.Length)
    let head = html.childElements.[0]
    let body = html.childElements.[1]
    let titleNode = head.childElements.[0]
    Assert.AreEqual("title", titleNode.tagName)
    Assert.AreEqual(1, titleNode.childNodes.Count)
    Assert.AreEqual("test", (titleNode.childNodes.[0] :?> Text).nodeValue)


[<Test>]
let testParseHtmlImplied() =
    // html/head,body tags are implied
    let html = """
    <title>test</title>
    test
    """
    let docNode = parse html
    let html = docNode.documentElement
    Assert.AreEqual(2, html.childElements.Length)
    let head = html.childElements.[0]
    let body = html.childElements.[1]
    let titleNode = head.childElements.[0]
    Assert.AreEqual("title", titleNode.tagName)
    Assert.AreEqual(1, titleNode.childNodes.Count)
    Assert.AreEqual("test", (titleNode.childNodes.[0] :?> Text).nodeValue)

[<Test>]
let testParseHtml2() =
    //test code
    let html = """
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    <p><b>B text</b></p>
    </body>
    </html>
    """
    let docNode = parse html
    Assert.AreEqual(1, docNode.childNodes.Count)
    let htmlNode = docNode.childElements.[0]
    Assert.AreEqual("html", htmlNode.tagName)
    Assert.AreEqual(2, htmlNode.childNodes.Count)
    let bodyNode = htmlNode.childElements.[1]
    Assert.AreEqual("body", bodyNode.tagName)
    Assert.AreEqual(1, bodyNode.childNodes.Count)
    let pNode = bodyNode.childElements.[0]
    let bNode = pNode.childElements.[0]
    let bTxt = bNode.childNodes.[0] :?> Text
    Assert.AreEqual("B text", bTxt.nodeValue)

[<Test>]
let testParseDump() =
    //test code
    let html = """
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    <p><b>B text</b></p>
    </body>
    </html>
    """
    let docNode = parse html
    let dump = dumpNode docNode
    Assert.AreEqual("(html (head (title 'test')) (body (p (b 'B text'))))", dump)

[<Test>]
let testHtmlCase() =
    //html is case insensitive
    let html = """
    <HTML>
    <heAd>
    <tItle>test</title>
    <style>a{b:C}</STYLe>
    </heaD>
    <body>
    <P><A hREF="abCd">B text</a></p>
    </body>
    </html>
    """
    let docNode = parse html
    let dump = dumpNode docNode
    // content is not case insensitive of course
    Assert.AreEqual("(html (head (title 'test') (style 'a{b:C}')) (body (p (a 'B text'))))", dump)
    let p = docNode.documentElement.bodyElement.childElements.[0]
    let a = p.childElements.[0]
    // Attribute names are case insensitive, but values are not
    Assert.AreEqual("abCd", a.attributes.["href"])

[<Test>]
let testParseScript() =
    // script elements may contain unescaped <
    let html = """
    <script> function(){ a<b>c } </script>
    """
    let docNode = parse html
    let dump = dumpNode docNode
    Assert.AreEqual("(html (head ) (body (script ' function(){ a<b>c }...')))", dump)

